// scripts/publish.js
import path from 'node:path'
import fs from 'node:fs'
import zlib from 'node:zlib'
import { globby, globbySync } from 'globby'
import inquirer from 'inquirer'
import fsExtra from 'fs-extra'
import shelljs from 'shelljs'
import request from 'request';
// import { execa, execaCommand, execaCommandSync } from 'execa'
const cwd = process.cwd()

const resolve = _path => path.resolve(cwd, _path);
const writeJSON = (path, json) => fsExtra.writeJSON(path, json, { spaces: 2 });

/**
 * 获取 widget 下的所有组件
 *
 * @returns {Map<any, any>}
 */
function getWidgets () {
  const packagePaths = globbySync('./src/widget', {
    cwd,
    onlyDirectories: true,
    deep: 1,
  })

  const widgets = new Map()
  packagePaths.forEach(item => {
    const name = item.split('/').pop()
    widgets.set(name, item)
  })

  return widgets
}

/**
 * 选择你要发布的包
 *
 * @param packages
 * @returns {Promise<*>}
 */
const choosePackage = async (packages) => {
  return await inquirer.prompt({
    type: 'list',
    name: 'packages',
    message: '选择你要发布的包:',
    choices: [...packages],
  })
}

/**
 * 选择版本号
 *
 * @param version
 * @returns {Promise<*>}
 */
async function selectedVersion(version) {
  const [ main, sub, revision ] = version.split('.');
  const choices = {
    type: 'list',
    name: 'packages',
    message: '选择包发布的版本:',
    choices: [
      version,
      `${ main }.${ sub }.${ +revision + 1 }`,
      `${ main }.${ +sub + 1 }.0`,
      `${ +main + 1 }.0.0`,
    ],
  }
  return inquirer.prompt(choices)
}

/**
 * 获取组件配置文件
 *
 * @returns {Promise<{name: *, version: string}|any>}
 */
async function getSetting (widgetPath) {
  const settingPath = resolve(`${widgetPath}/setting.tsx`)
  const hasSetting = await fsExtra.exists(settingPath)

  if (!hasSetting) {
    return console.warn(settingPath, '文件不存在！')
  }

  console.log('settingPath: => ', settingPath)
  let pattern = /["'`]([0-9]+(?:\.[0-9a-z]+)*)["'`]/i;
  const text = await fsExtra.readFile(settingPath, 'utf8')
  console.log('version: => ', text, text.match(pattern)[1])
  return {
    text,
    version: text.match(pattern)[1],
    path: settingPath,
  }
}

// 1. 获取 widget 下的所有组件
const widgets = getWidgets()

// 2. 选择要打包上传的组件
const { packages } = await choosePackage(widgets.keys())
const widgetPath = widgets.get(packages)

// 3. 获取组件配置文件
const setting = await getSetting(widgetPath)
if (setting.version) {
// 4. 选择版本号
  const { packages: newVersion } = await selectedVersion(setting.version);

  // 修改组件版本号
  if (setting.version !== newVersion) {
    setting.text = setting.text.replace(setting.version, newVersion);
    await fsExtra.writeFile(setting.path, setting.text);
  }

  // 5. 打包组件
  shelljs.exec(`npm run rollup -- --environment WIDGET_PATH:${packages}`)

  // 打包后的组件路径
  const buildFilePath = resolve(`./dist/${packages}.js`)
  const buildFilePathEsm = resolve(`./dist/${packages}.esm.mjs`)
  let hasWidget = await fsExtra.exists(buildFilePath)


  const { settings } = await import(`file://${buildFilePathEsm}`)
  console.log('settings: => ', settings)

  // 如果路径存在
  if (hasWidget) {
    // 6. 上传组件流
    pushWidget(buildFilePath, packages, settings)
  }
}

function pushWidget (filePath, name, config) {
  const read = fs.createReadStream(filePath)
  var formData = {
    filename: `${name}.${config.version}.js`,
    file: read,
  };

  request.post({ url: 'http://127.0.0.1:4003/api/file', formData: formData }, function fileCallback(error, httpResponse, body) {
    if (error) {
      return console.error('upload failed:', error);
    }
    if (body) body = JSON.parse(body)
    const headers = { "content-type": "application/json" }
    const { code, data } = body
    if (code === 200) {
      config.path = data
      config.name = name.toLocaleUpperCase()
      console.log('config: => ', config)
      request.post({ url: 'http://127.0.0.1:4003/api/widget', json: true, body: config, headers }, function
          widgetCallback(error, httpResponse, body) {
        if (error) {
          return console.error('upload failed:', error);
        }
        console.log('部件上传成功')
      })
    }
  })
}